public void getAllPersons(CustomerSortingOptions sortingOptions, Consumer<List<Customer>> customerConsumer) {
webClient.get()
.uri(uriBuilder -> uriBuilder
.path("customers")
.queryParam("sortField", sortingOptions.getSortField())
.queryParam("sortingOrder", sortingOptions.getSortingOrder())
.build())
.retrieve()
.bodyToMono(new ParameterizedTypeReference<List<Customer>>() {
})
.onErrorStop()
.subscribe(newPersons -> {
customers.clear();
customers.addAll(newPersons);
customerConsumer.accept(customers);
});
}public void addPerson(Customer customer, Consumer<List<Customer>> customerConsumer) {
// TODO Part 2: Complete the http post request to the server
webClient.post()
.uri("customers")
.bodyValue(customer)
.retrieve()
.bodyToMono(Customer.class)
.onErrorStop()
.subscribe(newCustomer -> {
customers.add(newCustomer);
customerConsumer.accept(customers);
});
}public void updatePerson(Customer customer, Consumer<List<Customer>> customerConsumer) {
// TODO Part 2: Complete the http put request to the server
webClient.put()
.uri("customers/" + customer.getId())
.bodyValue(customer)
.retrieve()
.bodyToMono(Customer.class)
.onErrorStop()
.subscribe(newCustomer -> {
customers.replaceAll(x -> x.getId().equals(customer.getId()) ? newCustomer : x);
customerConsumer.accept(customers);
});
}public void deletePerson(Customer customer, Consumer<List<Customer>> customerConsumer) {
// TODO Part 2: Make an http delete request to the server
webClient.delete()
.uri("customers/" + customer.getId())
.retrieve()
.toBodilessEntity()
.onErrorStop()
.subscribe(deletedCustomer -> {
customers.remove(customer);
customerConsumer.accept(customers);
});
}public CustomerController() {
this.webClient = WebClient.builder()
.baseUrl("http://localhost:8080/")
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
this.customers = new ArrayList<>();
}Docker reference: https://docs.docker.com/
https://docs.docker.com/get-started/docker-concepts/building-images/writing-a-dockerfile/ https://docs.docker.com/reference/dockerfile/
FROM python:3.13
WORKDIR /usr/local/app
# Install the application dependencies
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# Copy in the source code
COPY src ./src
EXPOSE 8080
# Setup an app user so the container doesn't run as the root user
RUN useradd app
USER app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]docker build -t <tag>docker psgRPC reference: https://grpc.io/docs/ gRPC Java basics: https://grpc.io/docs/languages/java/basics/
message Date {
int32 day = 1; // Number specifies order
int32 month = 2;
int32 year = 3;
}
message Location {
string city = 1;
string country = 2;
}
message LocationDate {
Location location = 1;
Date date = 2;
}service WeatherReporter {
//Returning one object
rpc GetCityWeatherSingleDay(LocationDate) returns (CityWeatherData) {}
// Returning a stream of objects
rpc GetCityWeatherMultipleDays(LocationDatePeriod) returns (stream CityWeatherData) {}
}In practice can be done with streams or with simple iteration
public void getCityWeatherSingleDay(LocationDate request, StreamObserver<CityWeatherData> responseObserver) {
var data = allWeatherData.stream().filter(cityWeatherData -> cityWeatherData.getLocationDate().equals(request)).findFirst().orElse(null);
if(data != null)responseObserver.onNext(data);
responseObserver.onCompleted();
}For returning a stream of data just call onNext multiple times:
public void getCityWeatherMultipleDays(LocationDatePeriod request, StreamObserver<CityWeatherData> responseObserver) {
for(CityWeatherData data : allWeatherData) {
if(data.getLocationDate().getLocation().equals(request.getLocation())) {
if(compareDate(data.getLocationDate().getDate(), request.getStartDate()) >= 0 && compareDate(data.getLocationDate().getDate(), request.getEndDate()) <= 0)
{
responseObserver.onNext(data);
}
}
}
responseObserver.onCompleted();
}public void getCityWeatherMultipleDays(LocationDatePeriod request, StreamObserver<CityWeatherData> responseObserver) {
var startDate = request.getStartDate();
var endDate = request.getEndDate();
allWeatherData.stream()
.filter(cityWeatherData -> cityWeatherData.getLocationDate().getLocation().equals(request.getLocation()))
.filter(cityWeatherData -> compareDate(cityWeatherData.getLocationDate().getDate(),startDate) >= 0)
.filter(cityWeatherData -> compareDate(cityWeatherData.getLocationDate().getDate(),endDate) <= 0)
.forEach(responseObserver::onNext);
responseObserver.onCompleted();
}